<script lang="tsx">
import { defineComponent, onMounted, type PropType, ref, unref, watch } from 'vue'
import type { Recordable } from '../types/form'
import { get, has, isArray, isFunction, isObject } from 'lodash-es'
import { useRuleFormItem } from '../common/useFormItem'
import { ElTreeSelect } from 'element-plus'
import type { OptionsItem } from '../types/formItem'
import { propTypes } from '@/types/propTypes'
type ResOpj = { code: number; data: OptionsItem[] | null }

export default defineComponent({
  name: 'ApiTreeSelect',
  props: {
    modelValue: {
      type: String as PropType<Recordable>,
    },
    api: {
      type: Function as PropType<(arg?: Recordable) => Promise<ResOpj>>,
      default: null,
    },
    // api params
    params: {
      type: Object as PropType<Recordable>,
      default: () => ({}),
    },
    // support xxx.xxx.xx
    resultField: propTypes.string.def(''),

    // 自定义部分选项
    innerOptions: {
      type: Array as PropType<OptionsItem[]>,
      default: () => [],
    },
  },
  emit: ['update:modelValue', 'options-change'],

  setup(props, { emit, attrs, slots }) {
    const treeData = ref<OptionsItem[]>([])
    const loading = ref(true)
    const [state] = useRuleFormItem(props, 'modelValue', 'change')

    watch(
      () => props.params,
      () => {
        fetch()
      },
      { deep: true },
    )
    watch(
      () => state.value,
      (v) => {
        emit('update:modelValue', v)
      },
    )
    onMounted(() => {
      fetch()
    })

    async function fetch() {
      const api = props.api
      if (!api || !isFunction(api)) return
      loading.value = true
      treeData.value = []
      try {
        loading.value = true
        const res = await api(props.params)
        // console.log("res", res)
        if (isObject(res)) {
          if (has(res, 'code') && res.code != 0) {
            return console.error('数据错误')
          }
          if (isArray(res.data)) {
            treeData.value = res.data
            if (props.innerOptions?.length) {
            }

            emitChange()
            return
          }
          //  a.b.c
          if (props.resultField) {
            treeData.value = get(res, props.resultField) || []
            if (props.innerOptions?.length) {
              treeData.value = props.innerOptions.concat(treeData.value)
            }
            emitChange()
          }
        }
        // 数组数据
        if (isArray(res)) {
          treeData.value = res
          if (props.innerOptions?.length) {
            treeData.value = props.innerOptions.concat(treeData.value)
          }
          emitChange()
          return
        }
      } catch (error) {
        console.warn(error)
      } finally {
        loading.value = false
      }
    }
    function emitChange() {
      emit('options-change', unref(treeData))
    }
    return () => {
      return (
        <div>
          <ElTreeSelect
            {...attrs}
            loading={loading.value}
            modelValue={state.value}
            data={treeData.value}
          >
            {{
              loading: () => <div>数据加载中...</div>,
              ...slots,
            }}
          </ElTreeSelect>
        </div>
      )
    }
  },
})
</script>
